import service from '@/axios/index'
import * as c from '@/util/config'
import qs from 'qs';
import lodash from 'lodash';
import {ElMessage} from 'element-plus'

//获取lodash工具类
export const _ = lodash;


/**
 * 判断字符串是否为null或者为''
 * @param str
 * @returns {*}
 */
export function isEmpty(str) {
    return str == null || str === '';
}

//获取接口的完整路径
export function getUrlAll(url) {
    return c.system.apiUrl + url + "?token=" + getToken();
}


//获取接口ip地址
export function getIp() {
    return c.system.apiUrl;
}


//复制一个对象reqForm
export function copyBean(obj) {
    return JSON.parse(JSON.stringify(obj));
}

//获取当前登录token
export function getToken() {
    return window.sessionStorage.getItem(c.sessionKey.TOKEN);
}


//同步get查询
export async function dic(url, data) {
    let result = {};
    await get(url, data).then(res => {
        result = res;
    })
    return result;
}


/**
 * 检测权限是否存在
 * @param code 编码
 * @returns {boolean}
 */
export function buttonPermissionsCheck(code) {
    let permissions = getSession(c.sessionKey.SYS_PERMISSIONS);
    //判断是否有当前权限
    return permissions.filter(x => x.code == code).length == 0 ? false : true;
}


/**
 * 获取session数据
 * @param key:键
 */
export function getSession(key) {
    return JSON.parse(window.sessionStorage.getItem(key));
}

/**
 * 设置session数据
 * @param key：键
 * @param value：值
 */
export function setSession(key, value) {
    window.sessionStorage.setItem(key, JSON.stringify(value));
}


/**
 * 清空session
 */
export function clearSession() {
    window.sessionStorage.clear();
}


export function uuid() {
    const s = [];
    const hexDigits = '0123456789abcdef';
    for (let i = 0; i < 36; i++) {
        s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
    }
    s[14] = '4';
    s[19] = hexDigits.substr((parseInt(s[19], 16) & 0x3) | 0x8, 1); // 注意此处 parseInt
    s[8] = s[13] = s[18] = s[23] = '-';

    return s.join('');
}


/**
 *  时间过滤器
 * @param date：时间
 * @param pattern：格式
 * @returns {string}
 */
export function fmtDate(date, pattern) {
    let ts = date.getTime();
    let d = new Date(ts).format("yyyy-MM-dd hh:mm:ss");
    if (pattern) {
        d = new Date(ts).format(pattern);
    }
    return d.toLocaleString();
}

//给Date类添加了一个新的实例方法format
Date.prototype.format = function (fmt) {
    //debugger;
    let o = {
        "M+": this.getMonth() + 1,                 //月份
        "d+": this.getDate(),                    //日
        "h+": this.getHours(),                   //小时
        "m+": this.getMinutes(),                 //分
        "s+": this.getSeconds(),                 //秒
        "q+": Math.floor((this.getMonth() + 3) / 3), //季度
        "S": this.getMilliseconds()             //毫秒
    };
    if (/(y+)/.test(fmt))
        fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
    for (let k in o)
        if (new RegExp("(" + k + ")").test(fmt))
            fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
    return fmt;
};


/**
 * axios封装请求
 * @param options 选项
 */
export function req(options) {
    let opt = _.merge({
        method: 'get'
    }, options);
    return service(opt)
        // 请求成功
        .then(function (resp) {
            return resp.code === 1 ? resp.data : null;
        });
}


/**
 *  axios delete请求
 * @param url
 * @param params
 * @returns {*}
 */
export function del(url, params) {
    let options = {
        url: url,
        params: params,
        method: 'DELETE'
    };
    return req(options);
}

/**
 *  axios get请求
 * @param url 请求地址
 * @param params 参数
 */
export function get(url, params) {
    let options = {
        url: url,
        params: params,
        method: 'GET'
    };
    return req(options);
}

/**
 * axios post请求
 * @param url
 * @param params
 * @returns {*}
 */
export function post(url, params) {
    let options = {
        url: url,
        data: params,
        method: 'POST'
    };
    return req(options);
}

/**
 * axios put请求
 * @param url
 * @param params
 * @returns {*}
 */
export function put(url, params) {
    let options = {
        url: url,
        data: params,
        method: 'put'
    };
    return req(options);
}


/**
 * axios 提交表单请求
 * @param options 选项
 * @returns {*}
 */
export function reqForm(options) {
    if (options.data) {
        options.data = qs.stringify(options.data);
    }
    return req(options);
}


/**
 * 上传文件
 * @param formData
 * @returns {*}
 */
export function uploadFile(formData) {
    let options = {
        url: "/file-info/uploadFile",
        data: formData,
        method: 'post',
        headers: {
            'Content-Type': 'multipart/form-data'
        }
    };
    return req(options);
}

/**
 * 获取下载文件的路径
 * @param fileId:文件id
 * @returns {string}
 */
export function getDownloadFileUrl(fileId) {
    return getIp() + `/file-info/downloadFile/${fileId}?token=` + getToken();
}

/**
 * 获取打开文件路径
 * @param fileId:文件id
 * @returns {string}
 */
export function getOpenFileUrl(fileId) {
    return getIp() + `/file-info/viewFileByWindow/${fileId}?token=` + getToken();
}


/**
 * 返回登录信息
 * @param info：登录后获取的信息
 */
export function setLoginInfo(info) {
    window.sessionStorage.setItem(c.sessionKey.TOKEN, info.token);
    setSession(c.sessionKey.USER_INFO, info.userInfo);
    setSession(c.sessionKey.SYS_MENU_TREE, info.userInfo.sysMenus);
    setSession(c.sessionKey.SYS_PERMISSIONS, info.userInfo.permissions);
}

/**
 * 查询树指定节点的路径
 * @param config：树的配置
 * @param tree：树
 * @param targetId：指定节点
 * @returns {null|*}
 */
export function findTreePath(config, tree, targetId) {
    if (config == null) {
        config = {
            id: "id",
            children: "children"
        }
    }

    function traverse(node, path) {
        path.push(node);

        if (node[config.id] === targetId) {
            return path;
        }

        if (node[config.children]) {
            for (const child of node[config.children]) {
                const result = traverse(child, path.slice());
                if (result) {
                    return result;
                }
            }
        }

        return null;
    }

    for (const root of tree) {
        const path = traverse(root, []);
        if (path) {
            return path;
        }
    }
    return null;
}

/**
 * 流式post请求
 * @param url:接口地址
 * @param body:参数
 * @param onChunk：每一段输出
 * @param onFinish：完整输出
 * @param onfirstChunk：第一次读
 * @param onError：异常
 */
export function streamPost(url, body, onChunk, onFinish, onfirstChunk, onError) {
    fetch(getUrlAll(url), {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            ...(getToken() ? {'X-Access-Token': getToken()} : {})
        },
        body: JSON.stringify(body)
    })
        .then(res => {
            if (!res.ok || !res.body) {
                throw new Error(`请求失败：${res.status}`);
            }
            const reader = res.body.getReader();
            const decoder = new TextDecoder('utf-8');
            let fullText = '';
            let index = 0;

            function read() {
                reader.read().then(({value, done}) => {
                    if (done) {
                        //读完回调
                        onFinish?.(fullText);
                        return;
                    }
                    const chunk = decoder.decode(value, {stream: true});
                    fullText += chunk;
                    //第一次读的回调
                    if (index === 0) {
                        onfirstChunk(fullText)
                        index++;
                    }
                    //每一次读回调
                    onChunk?.(chunk);
                    read(); // 继续读
                }).catch(err => {
                    onError?.(err);
                    ElMessage.error(`读取流失败: ${err.message}`);
                });
            }

            read();
        })
        .catch(err => {
            onError?.(err);
            ElMessage.error(`连接失败: ${err.message}`);
        });
}
